package rpc.common.utils;

import lombok.extern.slf4j.Slf4j;
import rpc.common.annotation.Service;
import rpc.common.annotation.ServiceScan;
import rpc.common.enumeraion.RpcError;
import rpc.common.exception.RpcException;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 服务扫描器
 */
@Slf4j
public class ServiceScanner {


    /**
     * 获取当前main方法全类名
     * @return
     */
    public static String getMainName() {
        StackTraceElement[] stack = new Throwable().getStackTrace();
        return stack[stack.length - 1].getClassName();
    }

    /**
     * 获取目录下符合要求的class
     * @param packageName
     * @return
     */
    public static Set<Class<?>> getClassesByPath(String packageName) {
        Set<Class<?>> classes = new LinkedHashSet<>();
        String packageDirName = packageName.replace('.', '/');
        log.debug("packageDirName: {}", packageDirName);
        try {
            Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            //log.debug("dirs: {}", dirs);
            while (dirs.hasMoreElements()) {
                URL url = dirs.nextElement();
                log.debug("url: {}", url);
                // 获取包的物理路径
                String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                File file = new File(filePath);
                if (file.isDirectory()) {
                    //目前只能遍历该目录class下文件
                    Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
                        @Override
                        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
                            File toFile = path.toFile();
                            //判断是否为class文件
                            if (toFile.getName().endsWith(".class")) {
                                String substring = toFile.getAbsolutePath().substring(file.getAbsolutePath().length());
                                if (substring.startsWith(File.separator)) {
                                    substring = substring.substring(1);
                                }
                                substring = substring.replace(File.separator, ".");
                                log.debug("File finded: {}", substring);
                                String className = substring.substring(0, substring.length() - 6);


                                try {
                                    classes.add(Class.forName(packageName + '.' + className));
                                } catch (ClassNotFoundException e) {
                                    e.printStackTrace();
                                }
                            }
                            //待扩展
                            //读取jar包
                            return super.visitFile(path, attrs);
                        }
                    });
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return classes;
    }

}
